package fra;

import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class M {
	/**
	 * 求最大公约数
	 * @param l1
	 * @param l2
	 * @return
	 */
	public static long GCD(long l1,long l2){
		if(l1==0)return 0l;
		if(l2==0)return l1;
		return GCD(l2,l1%l2);
	}
	public static BigInteger GCD(BigInteger l1,BigInteger l2){
		if(l1.signum()==0||l2.signum()==0)return new BigInteger(l1.toString());
		return GCD(l2,l1.mod(l2));
	}
	/**
	 * 求最大公约数
	 * @param l1
	 * @param l2
	 * @return
	 */
	public static Fra GCD(Fra f1,Fra f2){
		BigInteger l1=GCD(f1.getNumerator(),f2.getNumerator());
		BigInteger l2=GCD(f1.getDenominator(),f2.getDenominator());
		return new Fra(l1,l2);
	}
	
	/**
	 * 求最小公倍数
	 * @param l1
	 * @param l2
	 * @return
	 */
	public static long LCM(long l1,long l2){
		return l1/GCD(l1,l2)*l2;
	}
	/**
	 * 求最小公倍数
	 * @param l1
	 * @param l2
	 * @return
	 */
	public static Fra LCM(Fra f1,Fra f2){
		BigInteger l1=GCD(f1.getNumerator(),f2.getNumerator());
		BigInteger l2=GCD(f1.getDenominator(),f2.getDenominator());
		return new Fra(f1.getNumerator().divide(l1).multiply(f2.getNumerator()),f1.getDenominator().divide(l2).multiply(f2.getDenominator()));
	}
	/**关于Fra分数的运算************************************************/
	/**
	 * 加法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static Fra plus(Fra f1,Fra f2){
		Fra f=f1.clone();
		f.plus(f2);
		return f;
	}
	/**
	 * 减法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static Fra minis(Fra f1,Fra f2){
		Fra f=f1.clone();
		f.minis(f2);
		return f;		
	}
	/**
	 * 乘法运算
	 * @return
	 */
	public static Fra multiplication(Fra f1,Fra f2){
		Fra f=f1.clone();
		f.multiplication(f2);
		return f;		
	}
	/**
	 * 除法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static Fra division(Fra f1,Fra f2){
		Fra f=f1.clone();
		f.division(f2);
		return f;	
	}
	
	/**
	 * 分数矩阵运算
	 */
	/**
	 * 加法
	 * @param f2
	 * @return
	 */
	public static MatrixFra plus(MatrixFra f1,MatrixFra f2){
		if(!f1.size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j,plus(f1.get(i, j),f2.get(i, j)));
			}
		}
		return f;
	}
	/**
	 * 减法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra minis(MatrixFra f1,MatrixFra f2){
		if(!f1.size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j,minis(f1.get(i, j),f2.get(i, j)));
			}
		}
		return f;
	}
	/**
	 * 乘法运算
	 * @return
	 */
	public MatrixFra multiplication(MatrixFra f1,MatrixFra f2){
		if(!f1.size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j,multiplication(f1.get(i, j),f2.get(i, j)));
			}
		}
		return f;
	}
	/**
	 * 乘法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra multiplicationE(MatrixFra f1,MatrixFra f2){
		if(f1.size.col!=f2.size.row){
			throw new RuntimeException("两矩阵行列不一致");
		}
		MatrixFra mf=MatrixFra.zeros(new Size(f1.getRow(), f2.getCol()));
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f2.getCol(); j++) {
				for (int k = 0; k < f1.getCol(); k++) {
					mf.set(i,j,mf.get(i, j).plus(multiplication(f1.get(i, k), f2.get(k,j))));
				}
			}
		}
		return mf;
	}
	/**
	 * 除法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra division(MatrixFra f1,MatrixFra f2){
		if(!f1.size.equals(f2.size)){
			throw new RuntimeException("两矩阵行列不一致");
		}
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j,division(f1.get(i, j),f2.get(i, j)));
			}
		}
		return f;		
	}
	
	/**
	 * 加法
	 * @param f2
	 * @return
	 */
	public MatrixFra plus(MatrixFra f1,Fra f2){
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j, plus(f1.get(i, j), f2));
			}
		}
		return f;		
	}
	/**
	 * 减法
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra minis(MatrixFra f1,Fra f2){
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j, minis(f1.get(i, j), f2));
			}
		}
		return f;			
	}
	/**
	 * 乘法运算
	 * @return
	 */
	public MatrixFra multiplication(MatrixFra f1,Fra f2){
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j, multiplication(f1.get(i, j), f2));
			}
		}
		return f;	
	}
	/**
	 * 除法 左
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra division(MatrixFra f1,Fra f2){
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j, division(f1.get(i, j),f2));
			}
		}
		return f;	
	}
	/**
	 * 除法 右
	 * @param f1
	 * @param f2
	 * @return
	 */
	public MatrixFra division(Fra f2,MatrixFra f1){
		MatrixFra f=new MatrixFra(f1.size);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				f.set(i, j, division(f2,f1.get(i, j)));
			}
		}
		return f;
	}
	
	/**
	 * 矩阵合并 左右
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static MatrixFra combineLR(MatrixFra f1,MatrixFra f2){
		if(f1.getRow()>f2.getRow()){
			f2=expand(f2,new Size(f1.getRow(),f2.getCol()));
		}else if(f1.getRow()<f2.getRow()){
			f1=expand(f1,new Size(f2.getRow(),f1.getCol()));
		}
		MatrixFra mf=new MatrixFra(new Size(f1.getRow(), f1.getCol()+f2.getCol()));
		for (int i = 0; i < mf.getRow(); i++) {
			for (int j = 0; j < mf.getCol(); j++) {
				if(j<f1.getCol()){
					mf.set(i, j,f1.get(i, j));
				}else{
					mf.set(i, j,f2.get(i, j-f1.getCol()));
				}
			}
		}
		return mf;
	}
	/**
	 * 矩阵合并 上下
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static MatrixFra combineUD(MatrixFra f1,MatrixFra f2){
		return null;
	}
	/**
	 * 矩阵扩张
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static  MatrixFra expand(MatrixFra f1,Size size){
		Size Size0=new Size(Math.max(size.row, f1.getRow()), Math.max(size.col, f1.getCol()));
		MatrixFra mf=MatrixFra.zeros(Size0);
		for (int i = 0; i < f1.getRow(); i++) {
			for (int j = 0; j < f1.getCol(); j++) {
				mf.set(i, j, f1.get(i, j));
			}
		}
		return mf;
	}
	
	/**关于Fra比较************************************************/
	
	/**
	 * 分数比较
	 * @param f1
	 * @param f2
	 * @return
	 */
	public static int compare(Fra f1,Fra f2){
		return minis(f1, f2).getSign();
	}
	
	/**
	 * 相反数
	 * @return
	 */
	public static Fra opposite_number(Fra fra){
		return fra.clone().opposite_number();
	}
	/**
	 * 倒数
	 * @return
	 */
	public static Fra reciprocal(Fra fra){
		return fra.clone().reciprocal();
	}
	/**
	 * 绝对值
	 * @return
	 */
	public static Fra absolute_value(Fra fra){
		return fra.absolute_value();
	}
	public static void main(String[] args) {
		//System.out.println(GCD(12,12));
		System.out.println(toString("-10.0008"));
	}
	
	/**
	 * 交换
	 * @param f1
	 * @param f2
	 */
	public static void swap(Fra f1,Fra f2){
		Fra f=f1.clone();
		f1.set(f2);
		f2.set(f);
	}
	/**
	 * 将double格式化
	 * @param d
	 * @param a
	 * @return
	 */
	public static String toString(String str){
//		String regex1="([1-9][0-9]*[.][0-9]*[1-9])";
//		String regex2="(0[.][0-9]*[1-9])";
//		String regex3="([1-9][0-9]*)";
//		String regex4="(0)";
		Matcher m=Pattern.compile("([-]{0,1}[1-9][0-9]*[.][0-9]*[1-9])").matcher(str);
		if(m.find())return m.group();
		m=Pattern.compile("([-]{0,1}0[.][0-9]*[1-9])").matcher(str);
		if(m.find())return m.group();
		m=Pattern.compile("([-]{0,1}[1-9][0-9]*)").matcher(str);
		if(m.find())return m.group();
		m=Pattern.compile("(0)").matcher(str);
		if(m.find())return m.group();
		return str;
	}
}
